package com.lin.manager.system.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lin.manager.common.ex.BizException;
import com.lin.manager.common.utils.TreeUtil;
import com.lin.manager.redis.constants.RedisConstants;
import com.lin.manager.redis.service.RedisService;
import com.lin.manager.system.dao.SysAreaDao;
import com.lin.manager.system.entity.SysAreaEntity;
import com.lin.manager.system.model.vo.AreaVo;
import com.lin.manager.system.service.SysAreaService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @作者: 林江
 * @创建时间: 2024/4/20
 * @功能:
 */
@Service
public class SysAreaServiceImpl extends ServiceImpl<SysAreaDao, SysAreaEntity> implements SysAreaService {
    private static final String URL = "https://restapi.amap.com/v3/config/district?key=da533f1c79d925a6a5a7f88b352f7af0&subdistrict=3&extensions=base";
    private String[] arr = {"省", "市", "区"};
    final RestTemplate restTemplate = new RestTemplate();

    @Autowired
    SysAreaDao sysAreaDao;
    @Autowired
    RedisService redisService;


    @Override
    public List<AreaVo> listTree(String name, Integer level) {
        TreeUtil tree = TreeUtil.builder().parentIdName("pid").build();

        // 获取所有地点
        List<AreaVo> data = redisService.executeLock(() -> this.list(), SysAreaService.class.getName(), "cacheTree", List.class);

        // 内嵌层级
        List<AreaVo> finalData = data.stream().filter(item -> item.getLevel() <= level).collect(Collectors.toList());


        if (StringUtils.hasText(name)) {
            if (checkAreaName(name)) {
                return finalData.stream().filter(item -> item.getName().length() >= name.length() && item.getName().indexOf(name) != -1).map(item -> {
                    List<AreaVo> list = tree.tree(finalData, item.getId(), AreaVo.class);
                    item.setChildren(list);
                    return item;
                }).collect(Collectors.toList());
            }
        } else {
            return tree.tree(finalData, 0, AreaVo.class);
        }
        return new ArrayList<>();
    }

    @Override
    public void add(String name) {
        // 清除缓存
        redisService.delete(RedisConstants.REDISSON.concat(SysAreaService.class.getName()));

        if (checkAreaName(name)) {
            // 发送API请求并解析返回的JSON数据
            String response = restTemplate.getForObject(URL + "&keywords=" + name, String.class);
            // 解析response的JSON数据，提取地点信息并保存到数据库中
            JSONObject jsonObject = JSON.parseObject(response);
            add(jsonObject, 0l, 1);
        } else {
            throw new BizException("请检查地点名。只能以省，市，区，结尾");
        }
    }

    private void add(JSONObject jsonObject, Long pid, Integer level) {
        List<JSONObject> list = (List<JSONObject>) jsonObject.get("districts");
        if (list != null && list.size() > 0) {
            for (JSONObject obj : list) {
                SysAreaEntity area = new SysAreaEntity();
                area.setPid(pid);
                area.setLevel(level);
                area.setName(obj.get("name").toString());
                area.setCCode(obj.get("citycode").toString());
                area.setDCode(obj.get("adcode").toString());
                area.setCoordinate(obj.get("center").toString());
                sysAreaDao.insert(area);

                add(obj, area.getId(), area.getLevel() + 1);
            }
        }
    }

    /**
     * 获取所有的地点
     *
     * @return
     */
    private List<AreaVo> list1() {
        return sysAreaDao.selectList(null).stream().map(item -> {
            AreaVo areaVo = new AreaVo();
            BeanUtils.copyProperties(item, areaVo);
            return areaVo;
        }).collect(Collectors.toList());
    }

    /**
     * 校验地点名，只能以省，市，区，结尾
     *
     * @param key
     * @return
     */
    @NotNull
    private Boolean checkAreaName(String key) {
        for (String area : arr) {
            if (key.endsWith(area)) {
                return true;
            }
        }
        return false;
    }
}
